package com.yxw.blog.service;

import com.yxw.blog.bean.entity.Article;
import com.yxw.blog.bean.entity.Great;
import com.yxw.blog.bean.entity.User;
import com.yxw.blog.bean.response.ResponseCode;
import com.yxw.blog.conf.exception.BlogException;
import com.yxw.blog.dao.ArticleDao;
import com.yxw.blog.dao.GreatDao;
import com.yxw.blog.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.sql.SQLException;
import java.util.*;

/**
 * @author yexinwei
 */
@Service
public class ArticleService {

    @Autowired
    UserDao userDao;
    @Autowired
    ArticleDao articleDao;
    @Autowired
    GreatDao greatDao;

    /**
     *添加文章
     */
    @Transactional(rollbackFor = Exception.class)
    public void addArticle(String title , String content , HttpSession session) throws Exception {
        //通过session获得userId
        Integer userId = (Integer) session.getAttribute("userId");
        //获得此时的时间
        Date date = new Date();
        //通过userId获得User
        User user = userDao.getUserById(userId);
        //在用户文件夹下的Article文件夹中创建一个txt文件,名字为文章的标题
        File articleFile = new File(System.getProperty("user.dir")+"\\User\\"+user.getUserName()+"\\Article\\"+title+".txt");
        if(!articleFile.exists()){
            articleFile.createNewFile();
        }
        //向txt文件中写入文章
        FileWriter fileWriter = new FileWriter(articleFile,true);
        fileWriter.append(content);
        fileWriter.flush();
        //获取articleUrl
        String articleUrl = System.getProperty("user.dir")+"\\User\\"+user.getUserName()+"\\Article\\"+title+".txt";
        Integer great = 0;
        //将文章存入数据库
        Integer successInsert = articleDao.insertArticle(userId,title,date,articleUrl,great);
        //判断是否存入成功
        if(successInsert!=1){
            throw new BlogException(ResponseCode.DATABASE_FAILED);
        }
    }
    /**
     * 显示所有人的文章列表
     * 返回一个文章的List
     */
    public List<Article> showArticleList() {
        List<Article> articleList = articleDao.getArticleList();
        return articleList;
    }

    /**
     * 显示个人的文章列表
     * 返回一个文章的List
     */
    public List<Article> showMyArticleList(HttpSession session) {
        Integer userId = (Integer) session.getAttribute("userId");
        List<Article> articleList = articleDao.getArticleByUserId(userId);
        return articleList;
    }

    /**
     *显示具体的文章
     * 返回一个map类型数据
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String,Object> showArticle(String articleUrl , Integer articleId , HttpSession session) throws IOException {
            Map<String,Object> map = new HashMap<>();
            //通过session获取userId
            Integer userId = (Integer)session.getAttribute("userId");
            //通过articleUrl获取文章
            BufferedReader in = new BufferedReader(new FileReader(articleUrl));
            StringBuilder sb = new StringBuilder();
            String str;
            while ((str = in.readLine()) != null) {
                sb.append(str);
            }
            String article = sb.toString();
            //将文章放入map中
            map.put("article",article);
            //判断该用户是否给这篇文章点赞
            boolean flag = false;
            //通过userId 和 articleId 获取 great
            Great great = greatDao.getGreatByArticleIdAndUserId(userId,articleId);
            //判断great是否为空，为空则没点赞
            if(great==null){
                flag = false;
            }else{
                flag = true;
            }
            //将flag存入map中返回
            map.put("flag",flag);
            return map;
    }

    /**
     * 删除文章
     * 参数为文章的id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteArticle(Integer articleId ) throws Exception {
        //通过articleId获取Article
        Article article = articleDao.getArticleById(articleId);
        //通过article获取articleUrl
        String articleUrl = article.getArticleUrl();
        //删除文章存放的文件
        File file = new File(articleUrl);
        if(file.exists()){
            file.delete();
        }else{
            throw new BlogException(ResponseCode.FILE_FAILED);
        }
        //从数据库中删除文章
        Integer res1 = articleDao.deleteArticleById(articleId);
        if(res1!=null && res1!=1){
            throw new BlogException(ResponseCode.DATABASE_FAILED);
        }
        //删除文章的点赞记录
        Integer res2 = greatDao.deleteByArticleId(articleId);
        if(res2!=null && res2!=1){
            throw new BlogException(ResponseCode.DATABASE_FAILED);
        }
    }

    /**
     * 点赞功能
     */
    @Transactional(rollbackFor = Exception.class)
    public void addArticleGreat(Integer greatArticleId, HttpSession session) throws Exception {
        //通过session获得userId
        Integer userId = (Integer)session.getAttribute("userId");
        //修改article中的数据，另great+1
        Integer res1 = articleDao.addArticleGreat(greatArticleId);
        if(res1!=1){
            throw new SQLException();
        }
        //修改great表，新增一条数据
        Integer res2 = greatDao.insertGreat(userId,greatArticleId);
        if(res2!=1){
            throw new SQLException();
        }
    }

    /**
     *取消赞功能
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleterGreat(Integer deleteGreatArticleId, HttpSession session) throws SQLException {
        //通过session 获得userId
        Integer userId = (Integer)session.getAttribute("userId");
        //删除great表格中的数据
        Integer res1 = greatDao.deleteByArticleIdAndUserId(deleteGreatArticleId,userId);
        if(res1!=1){
            throw new SQLException();
        }
        //更新article表中的赞数目
        Integer res2 = articleDao.updateArticleByArticleId(deleteGreatArticleId);
        if(res2!=1){
            throw new SQLException();
        }
    }

    /**
     * 异步存图片
     */
    public Map<String,Object> uploadImage(MultipartFile file , HttpSession session){
        //通过session获取userId
        Integer userId = (Integer)session.getAttribute("userId");
        //通过userId 得到User对象
        User user = userDao.getUserById(userId);
        //最后按照layui官网定义返回的结果
        Map<String,Object> mv=new HashMap<String, Object>();
        Map<String, String> mvv = new HashMap<String, String>();
        //得到后缀名
        String fileExtension =  file.getOriginalFilename().substring( file.getOriginalFilename().indexOf("."));
        //生成一个UUID为图片命名
        String papername= UUID.randomUUID().toString().replace("-", "") + fileExtension;
        File destfile = new File(System.getProperty("user.dir")+"\\User\\"+user.getUserName()+"\\ArticleImage\\"+papername);
        try {
            //没有就新建
            if (!destfile.exists()) {
                destfile.mkdirs();
            }
            file.transferTo(destfile);
            //返回一个地址，这个地址不是文件的储存地址，而是前端访问地址
            mvv.put("src", "/article/showimg/" + papername);
            mvv.put("title",papername);
            mv.put("code", 0);
            mv.put("msg", "上传成功");
            mv.put("data", mvv);
            return mv;
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            mv.put("success", 1);
            return mv;
        }
        return mv;
    }

    /**
     * 图片回显
     */
    public void loadrichtext(String name, HttpServletResponse response , HttpSession session){
        //通过session获取userId
        Integer userId = (Integer)session.getAttribute("userId");
        //通过userId获取User
        User user = userDao.getUserById(userId);
        //获取到图片
        File file = new File(System.getProperty("user.dir") + "\\User\\"+ user.getUserName() + "\\ArticleImage\\" + name);
        ServletOutputStream out = null;
        try {
            FileInputStream in = new FileInputStream(file);
            out = response.getOutputStream();
            byte[] bytes = new byte[1024 * 100];
            // 读取长度
            int length = 0;
            while ((length = in.read(bytes)) != -1) {
                out.write(bytes, 0, length);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
